#!/bin/sh
# PCP QA Test No. 273
# Increase testing code coverage in core parts of libpcp
#
# Copyright (c) 2010 Ken McDonell.  All Rights Reserved.
#

seq=`basename $0`
echo "QA output created by $seq"

# get standard environment, filters and checks
. ./common.product
. ./common.filter
. ./common.check

[ -d $PCP_PMDAS_DIR/simple ] || _notrun "simple PMDA directory is not installed"

_cleanup()
{
    _restore_primary_logger
    _restore_auto_restart pmlogger
    $sudo rm -f $tmp.* simple.log*
    exit $status
}

status=1
trap "_cleanup" 0 1 2 3 15

# don't need to regenerate config.default with pmlogconf
#
export PMLOGGER_CHECK_SKIP_LOGCONF=yes

_stop_auto_restart pmlogger

_filter()
{
    sed \
	-e 's/0x[0-9a-f][0-9a-f]*/HEX/g' \
	-e '/version=[0-9]/s//version=N/' \
	-e '/code=[0-9]/s//code=N/' \
    # end
}

# Note - sed at the end is because of non-determinism depending if the
# 	 kernel PMDA is configured to use a dso or other IPC option
#      - pmWhichContext() is called different numbers of times depending
#        on how libpcp was compiled, so strip these lines
#
_filter2()
{
    sed \
	-e '/^pmWhichContext()/d' \
	-e '/pmResult/s/ .* numpmid/ ... numpmid/' \
	-e '/build_dsotab/s/parsing .*/ parsing .../' \
	-e '/^\[[0-9][0-9]*]/d' \
	-e '/^0x[0-9a-f][0-9a-f]* \[[0-9][0-9]*]/d' \
	-e '/^__pmLocalPMDA/d' \
	-e '/^Local Context PMDA Table$/d' \
	-e '/__pmConnectLogger:/s/pid = [0-9][0-9]*/pid = PID/' \
	-e 's/fd=[0-9][0-9]*/fd=N/g' \
	-e '/IPC table fd/s/:.*/: .../' \
	-e '/__pmSendCreds/s/:.*/: .../' \
	-e '/NotifyEndLocalContext: /s/:.*/: .../' \
	-e '/value /s/ [0-9].*/ NUMBER/' \
	-e '/^__pmDataIPC:/d' \
	-e '/^__pmSetDataIPC:/{
N
d
}' \
	-e 's/Permission denied/No permission to perform requested operation/' \
	-e '/__pmConnect(fd=/d' \
    | perl -ne '
	# squash repeated occurrences of the following pattern
	# (as a result of needing to do getaddrinfo list walk)
	if (/^IPC table fd.PDU version.: ...$/) {
	    $saved[1] = $_;
	} elsif (/^__pmSetSocketIPC: fd=N$/) {
	    $saved[0] = $_;
	} else {
	    if ($#saved >= 0) { print $saved[0]; }
	    if ($#saved == 1) { print $saved[1]; }
	    @saved = undef;
	    print;
	}' \
    | sed \
	-e '/^__pmSetSocketIPC:/d' \
	-e '/^NotifyEndLocalContext/d' \
	-e '/^IPC table fd/d' \
	-e '/version=[0-9]/s//version=N/' \
	-e '/code=[0-9]/s//code=N/' \
    # end
}

_filter3()
{
    sed \
	-e 's/Connection timed out/No route to host/' \
	-e '/version=[0-9]/s//version=N/' \
	-e '/code=[0-9]/s//code=N/' \
    # end
}

# simple PMDA is using PMDA_INTERFACE_2
#
if [ ! -f $PCP_PMDAS_DIR/simple/pmda_simple.$DSO_SUFFIX ]
then
    ( cd $PCP_PMDAS_DIR/simple; $sudo make; $sudo ./Install </dev/null ) >/dev/null 2>&1
fi

# real QA test starts here
_change_config pmcd on || _exit 1
_change_config pmlogger on || _exit 1
_writable_primary_logger
if ! _service pmcd restart 2>&1; then _exit 1; fi \
| _filter_pcp_restart
_wait_for_pmcd || _exit 1
if ! _service pmlogger restart 2>&1; then _exit 1; fi \
| _filter_pcp_restart
_wait_for_pmlogger || _exit 1

# help.c
#
echo "--- help.c case 1 ---"
$sudo_local_ctx pminfo -t -L sampledso 2>&1
echo "--- help.c case 2 ---"
$sudo_local_ctx pminfo -T -L sampledso 2>&1
echo "--- help.c case 3 ---"
pminfo -T -a tmparch/foo sample
echo "--- help.c case 4 ---"
$sudo_local_ctx pminfo -T -L -n $PCP_PMDAS_DIR/simple/root -K clear -K add,253,simple/pmda_simple.$DSO_SUFFIX,simple_init simple.now 2>&1

# instance.c
#
echo "--- instance.c case 1 ---"
$sudo_local_ctx pminfo -L -f -Dfetch sampledso.bin 2>&1 | _filter_dumpresult
echo "--- instance.c case 2 ---"
pminfo -f -Dindom sample.bin 2>&1 | _filter
echo "--- instance.c case 3 ---"
$sudo pminfo -fL -Dfetch,indom -n $PCP_PMDAS_DIR/simple/root -K clear -K add,253,simple/pmda_simple.$DSO_SUFFIX,simple_init simple 2>&1 \
| _filter_dumpresult | _filter
echo "--- instance.c case 4 ---"
src/indom sample.bin
echo "--- instance.c case 5 ---"
src/indom sample.long.one
echo "--- instance.c case 6 ---"
pmval -s 1 -i "bin-123" sample.bin
echo "--- instance.c case 7 (expect not output) ---"
$sudo_local_ctx src/torture_indom -L sampledso.colour 2>&1
echo "--- instance.c case 8 (expect not output) ---"
$sudo_local_ctx src/torture_indom -n $PCP_PMDAS_DIR/simple/root -K clear -K add,253,simple/pmda_simple.$DSO_SUFFIX,simple_init -L simple.now 2>&1

# fetchlocal.c
#
echo "--- fetchlocal.c case 1 ---"
$sudo_local_ctx pminfo -f -L -Dfetch sampledso.bad.unknown 2>&1 | _filter_dumpresult

# spec.c
#
echo "--- spec.c case 1 ---"
pminfo -f -h localhost:44321 sample.long.hundred
echo "--- spec.c case 2 ---"
pminfo -f -h localhost:1,44321 sample.long.hundred
echo "--- spec.c case 3 ---"
pminfo -f -h localhost: sample.long.hundred
echo "--- spec.c case 4 ---"
pminfo -f -h localhost:44321,1x3 sample.long.hundred
echo "--- spec.c case 5 ---"
pminfo -f -h localhost:44321@no-host sample.long.hundred 2>&1 | _filter3
echo "--- spec.c case 6 ---"
pminfo -f -h localhost:44321@no-host:44322 sample.long.hundred 2>&1 | _filter3
echo "--- spec.c case 7 ---"
pminfo -f -h localhost:44321@ sample.long.hundred

# units.c
#
# Pbyte / hour -> 1F055000
echo "--- units.c case 1 (expect not output) ---"
pmstore sample.dynamic.meta.pmdesc.units 0x1F055000 >/dev/null
echo "--- units.c case 2 ---"
pminfo -d sample.dynamic.meta.metric
# Ebyte / sec -> 1F063000
echo "--- units.c case 3 (expect not output) ---"
pmstore sample.dynamic.meta.pmdesc.units 0x1F063000 >/dev/null
echo "--- units.c case 4 ---"
pminfo -d sample.dynamic.meta.metric
# bigger than Ebyte -> 10070000
echo "--- units.c case 5 (expect not output) ---"
pmstore sample.dynamic.meta.pmdesc.units 0x10070000 >/dev/null
echo "--- units.c case 6 ---"
pminfo -d sample.dynamic.meta.metric
# bigger than Hour -> 01006000
echo "--- units.c case 7 (expect not output) ---"
pmstore sample.dynamic.meta.pmdesc.units 0x01006000 >/dev/null
echo "--- units.c case 8 ---"
pminfo -d sample.dynamic.meta.metric
# byte^2 -> 20000000
echo "--- units.c case 9 (expect not output) ---"
pmstore sample.dynamic.meta.pmdesc.units 0x20000000 >/dev/null
echo "--- units.c case 10 ---"
pminfo -d sample.dynamic.meta.metric
# nsec / byte -> F1000000
echo "--- units.c case 11 (expect not output) ---"
pmstore sample.dynamic.meta.pmdesc.units 0xF1000000 >/dev/null
echo "--- units.c case 12 ---"
pminfo -d sample.dynamic.meta.metric
# / byte^2 -> E0000000
echo "--- units.c case 13 (expect not output) ---"
pmstore sample.dynamic.meta.pmdesc.units 0xE0000000 >/dev/null
echo "--- units.c case 14 ---"
pminfo -d sample.dynamic.meta.metric
# nsec^3 -> 03000000
echo "--- units.c case 15 (expect not output) ---"
pmstore sample.dynamic.meta.pmdesc.units 0x03000000 >/dev/null
echo "--- units.c case 16 ---"
pminfo -d sample.dynamic.meta.metric
# / nsec^3 -> 0D000000
echo "--- units.c case 17 (expect not output) ---"
pmstore sample.dynamic.meta.pmdesc.units 0x0D000000 >/dev/null
echo "--- units.c case 18 ---"
pminfo -d sample.dynamic.meta.metric
# count^2 -> 00200000
echo "--- units.c case 19 (expect not output) ---"
pmstore sample.dynamic.meta.pmdesc.units 0x00200000 >/dev/null
echo "--- units.c case 20 ---"
pminfo -d sample.dynamic.meta.metric
# / count^2 -> 00E00000
echo "--- units.c case 21 (expect not output) ---"
pmstore sample.dynamic.meta.pmdesc.units 0x00E00000 >/dev/null
echo "--- units.c case 22 ---"
pminfo -d sample.dynamic.meta.metric
# restore to byte / sec -> 1F003000
echo "--- units.c case 23 (expect not output) ---"
pmstore sample.dynamic.meta.pmdesc.units 0x1F003000 >/dev/null

# units.c using grind_cov
#
for type in 0 1 2 3 4 5
do
    # space
    echo "--- units.c case 24 type=$type ---"
    src/grind_conv $type 1024 1:0:0:4:0:0 1:0:0:3:0:0
    echo "--- units.c case 25 type=$type ---"
    src/grind_conv $type 1048576 1:0:0:3:0:0 1:0:0:4:0:0
    # space / time
    echo "--- units.c case 26 type=$type ---"
    src/grind_conv $type 4096 1:-1:0:2:3:0 1:-1:0:3:5:0
    echo "--- units.c case 27 type=$type ---"
    src/grind_conv $type 14400 1:-1:0:3:5:0 1:-1:0:2:3:0
    # space-time / count
    echo "--- units.c case 28 type=$type ---"
    src/grind_conv $type 92160 1:1:-1:1:3:0 1:1:-1:2:4:1
    echo "--- units.c case 29 type=$type ---"
    src/grind_conv $type 15 1:1:-1:2:4:1 1:1:-1:1:3:0
    # time / space
    echo "--- units.c case 30 type=$type ---"
    src/grind_conv $type 1024 -1:1:0:2:3:0 -1:1:0:1:2:0
    echo "--- units.c case 31 type=$type ---"
    src/grind_conv $type 1000 -1:1:0:1:2:0 -1:1:0:2:3:0
done
# and some odd cases and error cases
echo "--- units.c case 41 ---"
src/grind_conv -Dvalue 3 4096 1:0:0:5:0:0 1:0:0:6:0:0
echo "--- units.c case 42 ---"
src/grind_conv 3 4 1:0:0:6:0:0 1:0:0:5:0:0
echo "--- units.c error case 43 ---"
src/grind_conv 3 4096 1:0:0:7:0:0 1:0:0:6:0:0
echo "--- units.c error case 44 ---"
src/grind_conv 3 4096 1:0:0:5:0:0 1:0:0:7:0:0
echo "--- units.c error case 45 ---"
src/grind_conv 3 3600 0:1:0:0:6:0 0:1:0:0:4:0
echo "--- units.c error case 46 ---"
src/grind_conv -Dvalue 3 3600 0:1:0:0:4:0 0:1:0:0:6:0
# dimensions not the same
echo "--- units.c error case 47 ---"
src/grind_conv 3 0 0:1:0:0:1:0 0:2:0:0:1:0
# cannot convert events
echo "--- units.c error case 48 ---"
src/grind_conv 8 0 0:1:0:0:1:0 0:1:0:0:1:0

# test the default pmUnits mapping
#
echo "--- default pmUnits none -> count"
src/grind_conv 3 123456 0:0:0:0:0:0 0:0:1:0:0:0
echo "--- default pmUnits count -> none"
src/grind_conv 3 123456 0:0:1:0:0:0 0:0:0:0:0:0

# units.c using src/xval
#
echo
echo "--- units.c case 32 ---"
src/xval -D 0x3fffffff 2>&1 \
| sed -e '/pmExtract.*AGGREGATE/{
s/feffff3f/3ffffffe/g
s/ffffff3f/3fffffff/g
s/00000040/40000000/g
}'
echo "--- units.c case 33 ---"
src/xval 0x7fffffff
echo "--- units.c case 34 ---"
src/xval 0xffffffff
echo "--- units.c case 35 ---"
src/xval 0x3fffffffffffffff
echo "--- units.c case 36 ---"
src/xval 0x7fffffffffffffff
echo "--- units.c case 37 ---"
src/xval 0xffffffffffffffff
echo "--- units.c case 38 ---"
src/xval -u 0xffffffffffffffff
echo "--- units.c case 39 ---"
src/xval -e

# store.c
#
echo "--- store.c case 1 ---"
$sudo_local_ctx src/chknumval -L sampledso.long.write_me sampledso.ulong.write_me sampledso.longlong.write_me >$tmp.out 2>$tmp.err
cat $tmp.err $tmp.out | _filter2

echo "--- store.c case 2 ---"
$sudo_local_ctx src/chknumval -Dcontext -L pmcd.control.debug sampledso.long.write_me sample.colour >$tmp.out 2>$tmp.err
cat $tmp.err $tmp.out | _filter2
cat >$tmp.root <<End-of-File
root {
    pmcd
    sample
    sampledso
}
pmcd {
    control
}
pmcd.control {
    debug 2:0:0
}
sample {
    colour 29:0:5
}
sampledso {
    long
}
sampledso.long {
    write_me 30:0:14
}
End-of-File

echo "--- store.c case 3 ---"
$sudo_local_ctx src/chknumval -L -n $tmp.root pmcd.control.debug sampledso.long.write_me sample.colour >$tmp.out 2>$tmp.err
cat $tmp.err $tmp.out | _filter2

echo "--- store.c case 4 ---"
$sudo_local_ctx src/chknumval -n $PCP_PMDAS_DIR/simple/root -K clear -K add,253,simple/pmda_simple.$DSO_SUFFIX,simple_init -L simple.now simple.now simple.now >$tmp.out 2>$tmp.err
cat $tmp.err $tmp.out | _filter2

# success, all done
status=0
exit
